package com.pcg.posgasstation.view;

import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.MifareClassic;
import android.nfc.tech.NfcA;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.pcg.posgasstation.R;
import com.pcg.posgasstation.base.BaseActivity;
import com.pcg.posgasstation.model.Constant;
import com.pcg.posgasstation.model.network.ApiClient;
import com.pcg.posgasstation.model.network.entity.BaseEntity;
import com.pcg.posgasstation.model.network.entity.GoodsItemEntity;
import com.pcg.posgasstation.model.network.entity.MemberInfoEntity;
import com.pcg.posgasstation.utils.LogUtil;
import com.pcg.posgasstation.utils.ToastUtils;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

public class MemberInfoActivity extends BaseActivity {

    @BindView(R.id.layTvBack)
    ImageView mLayTvBack;
    @BindView(R.id.layBack)
    RelativeLayout mLayBack;
    @BindView(R.id.layTvTitle)
    TextView mLayTvTitle;
    @BindView(R.id.btnSwipingCard)
    Button mBtnSwipingCard;
    @BindView(R.id.tvMemberName)
    TextView mTvMemberName;
    @BindView(R.id.layMemberName)
    LinearLayout mLayMemberName;
    @BindView(R.id.tvMemberCardName)
    TextView mTvMemberCardName;
    @BindView(R.id.layMemberCardName)
    LinearLayout mLayMemberCardName;
    @BindView(R.id.tvMemberPhone)
    TextView mTvMemberPhone;
    @BindView(R.id.layMemberPhone)
    LinearLayout mLayMemberPhone;
    @BindView(R.id.tvMemberType)
    TextView mTvMemberType;
    @BindView(R.id.layMemberType)
    LinearLayout mLayMemberType;
    @BindView(R.id.tvMemberBalance)
    TextView mTvMemberBalance;
    @BindView(R.id.layMemberBalance)
    LinearLayout mLayMemberBalance;
    @BindView(R.id.tvMemberInter)
    TextView mTvMemberInter;
    @BindView(R.id.layMemberInter)
    LinearLayout mLayMemberInter;
    @BindView(R.id.layCompany)
    LinearLayout mLayCompany;
    @BindView(R.id.tvCompanyName)
    TextView mTvCompanyName;
    @BindView(R.id.tvTotalMoney)
    TextView mTvTotalMoney;
    @BindView(R.id.tvCanUseMoney)
    TextView mTvCanUseMoney;
    @BindView(R.id.tvGoodLicense)
    TextView mTvGoodLicense;
    @BindView(R.id.layCanUserContainer)
    LinearLayout mLayCanUseContainer;
    @BindView(R.id.btnNext)
    Button mBtnNext;
    @BindView(R.id.layMemberInfo)
    LinearLayout mLayMemberInfo;
    @BindView(R.id.viewActionBarDivider)
    View mViewActionBarDivider;
    @BindView(R.id.layTotalMoney)
    LinearLayout mLayTotalMoney;
    @BindView(R.id.layCanUseMoney)
    LinearLayout mLayCanUseMoney;
    @BindView(R.id.layGoodLicense)
    LinearLayout mLayGoodLicense;

    private static final String TAG = MemberInfoActivity.class.getSimpleName();

    private GoodsItemEntity mItemEntity;
    private MemberInfoEntity mMemberInfoEntity;

    private LayoutInflater mLayoutInflater;

    // TEST
//    private String mNFCMemberCardNumber = "3206228629"; // NFC读取出来的卡号
//    private String mNFCMemberCardNumber = "021000003"; // NFC读取出来的卡号
//    private String mNFCMemberCardNumber = "4198767366"; // 企业会员
    private String mNFCMemberCardNumber = ""; // NFC读取出来的卡号

    // nfc begin
    private NfcAdapter mAdapter;
    private PendingIntent mPendingIntent;
    private NdefMessage mNdefPushMessage;

    private List<Tag> mTags = new ArrayList<Tag>();
    // nfc end

    public static void startActivity(Context context, GoodsItemEntity entity) {
        Intent intent = new Intent();
        intent.setClass(context, MemberInfoActivity.class);
        intent.putExtra("goods_item", entity);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_member_info);
        ButterKnife.bind(this);

        mLayoutInflater = LayoutInflater.from(mContext);
        initData();
        initViews();
        initNfc();
    }

    @OnClick(R.id.layBack)
    void backClick() {
        finish();
    }

    @OnClick(R.id.btnNext)
    void btnNextClick() {
        if (mMemberInfoEntity == null) {
            ToastUtils.showToast("请刷卡重试");
            return;
        }
        if (mMemberInfoEntity.getMembers_type() == Constant.Member.MEMBER_COMPANY
                || mMemberInfoEntity.getMembers_type() == Constant.Member.MEMBER_COMPANY_ADDITIONAL) {

            boolean hasGoodPermission = false;
            for (MemberInfoEntity.FoodPermitBean itemBean : mMemberInfoEntity.getFood_permit()) {
                if (itemBean != null && itemBean.getFood_id() == mItemEntity.getId()) {
                    hasGoodPermission = true;
                    break;
                }
            }

            if (hasGoodPermission) {
                CreateOrderActivity.startActivity(mContext, mItemEntity, mMemberInfoEntity);
            } else {
                ToastUtils.showToast("不能消费该商品");
            }

        } else {
            CreateOrderActivity.startActivity(mContext, mItemEntity, mMemberInfoEntity);
        }
    }

    // nfc begin

    @Override
    protected void onResume() {
        super.onResume();
        if (mAdapter != null) {
            if (!mAdapter.isEnabled()) {
                showWirelessSettingsDialog();
            }
            mAdapter.enableForegroundDispatch(this, mPendingIntent, null, null);
            mAdapter.enableForegroundNdefPush(this, mNdefPushMessage);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mAdapter != null) {
            mAdapter.disableForegroundDispatch(this);
            mAdapter.disableForegroundNdefPush(this);
        }
    }

    @Override
    public void onNewIntent(Intent intent) {
        setIntent(intent);
        resolveIntent(intent);
    }

    private void initNfc() {
        resolveIntent(getIntent());

        mAdapter = NfcAdapter.getDefaultAdapter(this);
        if (mAdapter == null) {
            ToastUtils.showToast("没有NFC");
//            finish();
            return;
        }

        mPendingIntent = PendingIntent.getActivity(this, 0,
                new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        mNdefPushMessage = new NdefMessage(new NdefRecord[]{newTextRecord(
                "Message from NFC Reader :-)", Locale.ENGLISH, true)});
    }

    private void showWirelessSettingsDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage(R.string.nfc_disabled);
        builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialogInterface, int i) {
                Intent intent = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
                startActivity(intent);
            }
        });
        builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialogInterface, int i) {
                finish();
            }
        });
        builder.create().show();
        return;
    }

    private NdefRecord newTextRecord(String text, Locale locale, boolean encodeInUtf8) {
        byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));

        Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
        byte[] textBytes = text.getBytes(utfEncoding);

        int utfBit = encodeInUtf8 ? 0 : (1 << 7);
        char status = (char) (utfBit + langBytes.length);

        byte[] data = new byte[1 + langBytes.length + textBytes.length];
        data[0] = (byte) status;
        System.arraycopy(langBytes, 0, data, 1, langBytes.length);
        System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);

        return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data);
    }

    private void resolveIntent(Intent intent) {
        String action = intent.getAction();
        if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
                || NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
                || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
            Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
            NdefMessage[] msgs;
            if (rawMsgs != null) {
                msgs = new NdefMessage[rawMsgs.length];
                for (int i = 0; i < rawMsgs.length; i++) {
                    msgs[i] = (NdefMessage) rawMsgs[i];
                }
            } else {
                // Unknown tag type
                byte[] empty = new byte[0];
                byte[] id = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
                Tag tag = (Tag) intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
                byte[] payload = dumpTagData(tag).getBytes();
                NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, id, payload);
                NdefMessage msg = new NdefMessage(new NdefRecord[]{record});
                msgs = new NdefMessage[]{msg};
                mTags.add(tag);
            }
            // Setup the views
            buildTagViews(msgs);
        }
    }

    private void buildTagViews(NdefMessage[] msgs) {
        if (msgs == null || msgs.length == 0) {
            return;
        }
        // Parse the first message in the list
        // Build views for all of the sub records
        NdefRecord[] ndefRecords = msgs[0].getRecords();
        if (ndefRecords != null && ndefRecords.length > 0) {
            byte[] playLoadByte = ndefRecords[0].getPayload();
            String textCardNum = new String(playLoadByte);
            LogUtil.e(TAG, "nfc record card number = " + textCardNum);

            mNFCMemberCardNumber = textCardNum;
            loadMemberInfo(mNFCMemberCardNumber);
        }

//        List<ParsedNdefRecord> records = NdefMessageParser.parse(msgs[0]);
//        final int size = records.size();
//        for (int i = 0; i < size; i++) {
//            ParsedNdefRecord record = records.get(i);
////            record.getView()
//            LogUtil.e(TAG,"nfc record");
//        }
    }

    private String dumpTagData(Tag tag) {
        StringBuilder sb = new StringBuilder();
        byte[] id = tag.getId();
        sb.append(toDec(id));

//        sb.append("ID (hex): ").append(toHex(id)).append('\n');
//        sb.append("ID (reversed hex): ").append(toReversedHex(id)).append('\n');
//        sb.append("ID (dec): ").append(toDec(id)).append('\n');
//        sb.append("ID (reversed dec): ").append(toReversedDec(id)).append('\n');

//        String prefix = "android.nfc.tech.";
//        sb.append("Technologies: ");
//        for (String tech : tag.getTechList()) {
//            sb.append(tech.substring(prefix.length()));
//            sb.append(", ");
//        }
//        sb.delete(sb.length() - 2, sb.length());
//        for (String tech : tag.getTechList()) {
//            if (tech.equals(MifareClassic.class.getName())) {
//                sb.append('\n');
//                String type = "Unknown";
//                try {
//                    MifareClassic mifareTag;
//                    try {
//                        mifareTag = MifareClassic.get(tag);
//                    } catch (Exception e) {
//                        // Fix for Sony Xperia Z3/Z5 phones
//                        tag = cleanupTag(tag);
//                        mifareTag = MifareClassic.get(tag);
//                    }
//                    switch (mifareTag.getType()) {
//                        case MifareClassic.TYPE_CLASSIC:
//                            type = "Classic";
//                            break;
//                        case MifareClassic.TYPE_PLUS:
//                            type = "Plus";
//                            break;
//                        case MifareClassic.TYPE_PRO:
//                            type = "Pro";
//                            break;
//                    }
//                    sb.append("Mifare Classic type: ");
//                    sb.append(type);
//                    sb.append('\n');
//
//                    sb.append("Mifare size: ");
//                    sb.append(mifareTag.getSize() + " bytes");
//                    sb.append('\n');
//
//                    sb.append("Mifare sectors: ");
//                    sb.append(mifareTag.getSectorCount());
//                    sb.append('\n');
//
//                    sb.append("Mifare blocks: ");
//                    sb.append(mifareTag.getBlockCount());
//                } catch (Exception e) {
//                    sb.append("Mifare classic error: " + e.getMessage());
//                }
//            }
//
//            if (tech.equals(MifareUltralight.class.getName())) {
//                sb.append('\n');
//                MifareUltralight mifareUlTag = MifareUltralight.get(tag);
//                String type = "Unknown";
//                switch (mifareUlTag.getType()) {
//                    case MifareUltralight.TYPE_ULTRALIGHT:
//                        type = "Ultralight";
//                        break;
//                    case MifareUltralight.TYPE_ULTRALIGHT_C:
//                        type = "Ultralight C";
//                        break;
//                }
//                sb.append("Mifare Ultralight type: ");
//                sb.append(type);
//            }
//        }

        return sb.toString();
    }

    private Tag cleanupTag(Tag oTag) {
        if (oTag == null)
            return null;

        String[] sTechList = oTag.getTechList();

        Parcel oParcel = Parcel.obtain();
        oTag.writeToParcel(oParcel, 0);
        oParcel.setDataPosition(0);

        int len = oParcel.readInt();
        byte[] id = null;
        if (len >= 0) {
            id = new byte[len];
            oParcel.readByteArray(id);
        }
        int[] oTechList = new int[oParcel.readInt()];
        oParcel.readIntArray(oTechList);
        Bundle[] oTechExtras = oParcel.createTypedArray(Bundle.CREATOR);
        int serviceHandle = oParcel.readInt();
        int isMock = oParcel.readInt();
        IBinder tagService;
        if (isMock == 0) {
            tagService = oParcel.readStrongBinder();
        } else {
            tagService = null;
        }
        oParcel.recycle();

        int nfca_idx = -1;
        int mc_idx = -1;
        short oSak = 0;
        short nSak = 0;

        for (int idx = 0; idx < sTechList.length; idx++) {
            if (sTechList[idx].equals(NfcA.class.getName())) {
                if (nfca_idx == -1) {
                    nfca_idx = idx;
                    if (oTechExtras[idx] != null && oTechExtras[idx].containsKey("sak")) {
                        oSak = oTechExtras[idx].getShort("sak");
                        nSak = oSak;
                    }
                } else {
                    if (oTechExtras[idx] != null && oTechExtras[idx].containsKey("sak")) {
                        nSak = (short) (nSak | oTechExtras[idx].getShort("sak"));
                    }
                }
            } else if (sTechList[idx].equals(MifareClassic.class.getName())) {
                mc_idx = idx;
            }
        }

        boolean modified = false;

        if (oSak != nSak) {
            oTechExtras[nfca_idx].putShort("sak", nSak);
            modified = true;
        }

        if (nfca_idx != -1 && mc_idx != -1 && oTechExtras[mc_idx] == null) {
            oTechExtras[mc_idx] = oTechExtras[nfca_idx];
            modified = true;
        }

        if (!modified) {
            return oTag;
        }

        Parcel nParcel = Parcel.obtain();
        nParcel.writeInt(id.length);
        nParcel.writeByteArray(id);
        nParcel.writeInt(oTechList.length);
        nParcel.writeIntArray(oTechList);
        nParcel.writeTypedArray(oTechExtras, 0);
        nParcel.writeInt(serviceHandle);
        nParcel.writeInt(isMock);
        if (isMock == 0) {
            nParcel.writeStrongBinder(tagService);
        }
        nParcel.setDataPosition(0);

        Tag nTag = Tag.CREATOR.createFromParcel(nParcel);

        nParcel.recycle();

        return nTag;
    }

    private String toHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (int i = bytes.length - 1; i >= 0; --i) {
            int b = bytes[i] & 0xff;
            if (b < 0x10)
                sb.append('0');
            sb.append(Integer.toHexString(b));
            if (i > 0) {
                sb.append(" ");
            }
        }
        return sb.toString();
    }

    private String toReversedHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; ++i) {
            if (i > 0) {
                sb.append(" ");
            }
            int b = bytes[i] & 0xff;
            if (b < 0x10)
                sb.append('0');
            sb.append(Integer.toHexString(b));
        }
        return sb.toString();
    }

    private long toDec(byte[] bytes) {
        long result = 0;
        long factor = 1;
        for (int i = 0; i < bytes.length; ++i) {
            long value = bytes[i] & 0xffl;
            result += value * factor;
            factor *= 256l;
        }
        return result;
    }

    private long toReversedDec(byte[] bytes) {
        long result = 0;
        long factor = 1;
        for (int i = bytes.length - 1; i >= 0; --i) {
            long value = bytes[i] & 0xffl;
            result += value * factor;
            factor *= 256l;
        }
        return result;
    }

    // nfc end

    private void initData() {
        mItemEntity = getIntent().getParcelableExtra("goods_item");
    }

    private void initViews() {
        mProgressDialog = new ProgressDialog(this);
        mLayTvTitle.setText("会员信息");
        loadMemberInfo(mNFCMemberCardNumber);
    }

    private void loadMemberInfo(final String card) {
        if (TextUtils.isEmpty(mNFCMemberCardNumber)) {
            return;
        }
        mProgressDialog.show();
        ApiClient.getApiService().getMemberInfo(ApiClient.getToken(), card)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<BaseEntity<MemberInfoEntity>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        mDisposable.add(d);
                    }

                    @Override
                    public void onNext(BaseEntity<MemberInfoEntity> entity) {
                        LogUtil.e(TAG, "loadMemberInfo " + card + " onNext");
                        mProgressDialog.hide();
                        if (entity != null) {
                            if (entity.isSuccess()) {
                                mMemberInfoEntity = entity.getData();
                                showMemberInfo(mMemberInfoEntity);
                            } else {
                                ToastUtils.showToast(entity.getMsg());
                            }
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        LogUtil.e(TAG, "loadMemberInfo onError");
                        e.printStackTrace();
                        mProgressDialog.hide();
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    private void showMemberInfo(MemberInfoEntity entity) {
        if (entity == null) {
            return;
        }
        mLayMemberInfo.setVisibility(View.VISIBLE);

        mTvMemberName.setText(entity.getLicense_corporation());
        mTvMemberCardName.setText(entity.getMembers_card());
        mTvMemberPhone.setText(entity.getTel());
        mTvMemberBalance.setText(String.valueOf(entity.getBalance()));
        mTvMemberInter.setText(String.valueOf(entity.getBalance_inter()));
        mTvMemberType.setText(getMemberType(entity.getMembers_type()) + "-" + getCashModel(entity.getCash_model()));

        if (entity.getFood_permit() != null) {
            List<MemberInfoEntity.FoodPermitBean> foodPermitBeans = entity.getFood_permit();
            String foodLicense = "";
            mLayCanUseContainer.removeAllViews();
            for (MemberInfoEntity.FoodPermitBean itemBean : foodPermitBeans) {
//                foodLicense = itemBean.getFood_name() + itemBean.getType_name() + " ";
                foodLicense = itemBean.getFood_name() + " ";
                View itemContent = mLayoutInflater.inflate(R.layout.layout_item_can_user_amount, null);
                TextView titleTextView = itemContent.findViewById(R.id.tvCanUseTitle);
                TextView canUseAmountTextView = itemContent.findViewById(R.id.tvCanUseAmount);

                titleTextView.setText(itemBean.getFood_name() + itemBean.getType_name() + "可用额度");
                canUseAmountTextView.setText(itemBean.getAmount());
                mLayCanUseContainer.addView(itemContent);
            }
            mTvGoodLicense.setText(foodLicense);
        }

        mTvCompanyName.setText(entity.getLicense_name());
        mTvTotalMoney.setText(entity.getTotal_amount_limit());
        mTvCanUseMoney.setText(entity.getAvailable_amount());

        if (entity.getMembers_type() == Constant.Member.MEMBER_PERSON) {
            hideSomeCompanyViews();
        }
    }

    private void hideSomeCompanyViews() {
        mLayCompany.setVisibility(View.GONE);
        mLayTotalMoney.setVisibility(View.GONE);
        mLayCanUseMoney.setVisibility(View.GONE);
        mLayGoodLicense.setVisibility(View.GONE);
    }

    private String getMemberType(int memberType) {
        if (memberType == Constant.Member.MEMBER_PERSON) {
            mLayCompany.setVisibility(View.GONE);
            return "个人用户";
        } else if (memberType == Constant.Member.MEMBER_COMPANY) {
            mLayCompany.setVisibility(View.VISIBLE);
            return "企业用户";
        } else if (memberType == Constant.Member.MEMBER_COMPANY_ADDITIONAL) {
            mLayCompany.setVisibility(View.VISIBLE);
            return "企业用户副卡";
        }
        return "企业用户";
    }

    private String getCashModel(int cashModel) {
        if (cashModel == 0) {
            return "储蓄卡";
        } else {
            return "后付款";
        }
    }

}
